<?php

namespace App\Models\Order;

use App\Libraries\Tools\ConstVar;
use App\Libraries\Tools\Tools;
use App\Models\BaseModel;
use App\Models\Post\Post;
use App\Models\Post\PostPurchase;
use App\Models\Product\Product;
use App\Models\Product\ProductPurchase;
use App\Models\Shop\ShopCouponPurchase;
use App\Models\Shop\ShopCoupon;
use App\Models\User\Balance;
use App\Models\User\User;
use Illuminate\Http\Request;

class Order extends BaseModel
{

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = [];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'sid',
        'buyer_channel_id',
        'buyer_channel_account',
        'updated_at'
    ];
    protected $dateFormat = 'U';

    /**
     * 添加订单
     * @param $type
     * @param $user_id
     * @param $object_id
     * @param $total_amount
     * @param $channel
     * @param $hong_bao_id
     * @param $hong_bao_amount
     * @return bool
     */
    public function add($type, $user_id, $object_id, $total_amount, $channel, $hong_bao_id, $hong_bao_amount){
        $this->type = $type;
        $this->channel = $channel;
        $this->user_id = $user_id;
        $this->object_id = $object_id;
        $this->total_amount = $total_amount;
        $this->hong_bao_id = $hong_bao_id;
        $this->hong_bao_amount = $hong_bao_amount;
        $this->save();
        return $this->id;
    }

    /**
     * 下单逻辑
     * @param Request $request
     * @param $user
     * @param $channel
     * @param Post|Product|User|ShopCoupon $model
     * @param null $model_ext
     * @return array
     */
    public function logic(Request $request, $user, $channel, $model, $model_ext=null){
        $rs = $model->beforeCheck($request, $model_ext);
        if($rs['code'] != 200){
            $this->rs_format['code'] = $rs['code'];
            return $this->rs_format;
        }
        switch($channel){
            case ConstVar::$ORDER_CHANNEL_BALANCE:
                $purchase_type = ConstVar::$PURCHASE_TYPE_BALANCE;
                $real_amount = $rs['data']['price'] - ($rs['data']['hong_bao_amount']??0);
                $flag = $user->where('user_id', $user->user_id)
                    ->where('balance', '>=', $real_amount)
                    ->decrement('balance', $real_amount);
                if(!$flag){
                    $this->rs_format['code'] = 40004;
                    return $this->rs_format;
                }
                $this->rs_format['data']['ext_id'] = $rs['data']['ext_id'];
                $this->rs_format['data']['price'] = $rs['data']['price'];
                $this->rs_format['data']['hong_bao_id'] = $rs['data']['hong_bao_id']??0;
                $this->rs_format['data']['hong_bao_amount'] = $rs['data']['hong_bao_amount']??0;
                break;
            default:
                $purchase_type = ConstVar::$PURCHASE_TYPE_MONEY;
                break;
        }

        $order_id = $this->add(
            $request['type'],
            $user->user_id,
            $request['id'],
            $rs['data']['price'],
            $channel,
            $rs['data']['hong_bao_id']??0,
            $rs['data']['hong_bao_amount']??0
        );

        switch($request['type']){
            case ConstVar::$ORDER_TYPE_POST:
                $postPurchase = new PostPurchase();
                $postPurchase->add($user->user_id, $request['id'], $purchase_type, $order_id);
                break;
            case ConstVar::$ORDER_TYPE_PRODUCT:
                $productPurchase = new ProductPurchase();
                $product = new Product();
                $productPurchase->add(
                    $user->user_id,
                    $request['id'],//product_id
                    $request['address_id'],//address_id
                    $purchase_type,
                    $product,
                    new User(),
                    $order_id,//order_id
                    $product->find($request['id'])->category==2?4:0//shipping_status
                );
                break;
            case ConstVar::$ORDER_TYPE_TRANSFER_TO_SHOP:
                break;
            case ConstVar::$ORDER_TYPE_COUPON:
                $shopCouponPurchase = new ShopCouponPurchase();
                $shopCouponPurchase->add(
                    $user->user_id,
                    $request['id'],//coupon_id
                    $rs['data']['ext_id'],//shop_id
                    $rs['data']['price'],
                    $purchase_type,
                    $order_id//order_id
                );
                break;
            case ConstVar::$ORDER_TYPE_TRANSFER_TO_USER:
                break;
            default:
                $this->rs_format['code'] = 50001;
                return $this->rs_format;
                break;
        }
        $this->rs_format['data']['body'] = Tools::cutString($rs['data']['body'], 10);
        $this->rs_format['data']['subject'] = '支付';
        //订单ID_购买类型_帖子ID_帖子作者ID 或者
        //订单ID_购买类型_商品ID_地址ID 或者
        //订单ID_购买类型_商家ID_0 或者
        //订单ID_购买类型_套餐ID_商家ID 或者
        //订单ID_购买类型_用户ID_0
        $this->out_trade_no = $this->rs_format['data']['out_trade_no'] = $this->id.'_'.$this->type.'_'.$request['id'].'_'.$rs['data']['ext_id'];
        $this->save();
        return $this->rs_format;
    }

    /**
     * 订单列表
     * @param $page
     * @param $size
     * @param $user_id
     * @param $status
     * @param $type
     * @return mixed
     */
    public function orders($page, $size, $user_id, $status, $type){
        $sql = $this->where('user_id', $user_id);
        if(!is_null($status)){
            $sql = $sql->where('status', $status);
        }
        if(!is_null($type)){
            $sql = $sql->where('type', $type);
        }
        $data['list'] = $sql->forPage($page, $size+1)
            ->get()
            ->toArray();
        $data['next_page'] = $page + 1;
        $data['page_size'] = $size;
        return $this->after($data);
    }

    /**
     * 订单列表V2
     * @param $page
     * @param $size
     * @param $user_id
     * @param $status
     * @param $type
     * @return mixed
     */
    public function ordersV2($page, $size, $user_id, $status, $type){
        $sql = $this->where('user_id', $user_id);
        if(isset($status)){
            $sql = $sql->whereIn('status', $status);
        }
        if(isset($type)){
            $sql = $sql->whereIn('type', $type);
        }
        $data['list'] = $sql->orderBy('id', 'desc')
            ->forPage($page, $size+1)
            ->get()
            ->toArray();
        $data['next_page'] = $page + 1;
        $data['page_size'] = $size;
        return $this->after($data);
    }
}
